package com.rex.saas.job;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.rex.saas.bean.DeviceBasicData;
import com.rex.saas.constants.Constants;
import com.rex.saas.db.entity.PaasGatewayCredentials;
import com.rex.saas.db.entity.PaasGatewayDeviceRelation;
import com.rex.saas.db.mapper.PaasGatewayCredentialsMapper;
import com.rex.saas.db.mapper.PaasGatewayDeviceRelationMapper;
import com.rex.saas.db.mapper.SaasUserInfoMapper;
import com.rex.saas.enums.GwStatusEnum;
import com.rex.saas.service.RexolarApiClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class GwDeviceSyncJob {
    @Autowired
    RexolarApiClient rexolarApiClient;

    @Autowired
    PaasGatewayCredentialsMapper gatewayCredentialsService;

    @Autowired
    PaasGatewayDeviceRelationMapper paasGatewayDeviceRelationService;

    @Autowired
    SaasUserInfoMapper saasUserInfoMapper;

    /**
     */
    @Scheduled(fixedRate = 60 * 1000)
    public void syncGwStatus() {
        long startTime = System.currentTimeMillis();
//        log.info("syncGwStatus start, time:{}", startTime);
        LambdaQueryWrapper<PaasGatewayCredentials> queryWrapper = new LambdaQueryWrapper<PaasGatewayCredentials>();
        queryWrapper.eq(PaasGatewayCredentials::getStatus, GwStatusEnum.CREATED.getCode());
        List<PaasGatewayCredentials> gwList = gatewayCredentialsService.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(gwList)){
//            log.info("syncGwStatus no gw to sync");
            return;
        }

        for (PaasGatewayCredentials gw : gwList) {
            String tenantId = gw.getTenantId();
            String token = rexolarApiClient.getTenantToken(tenantId);
            if(StringUtils.isEmpty(token)){
//                log.error("syncGwStatus getToken error, tenantId:{}", tenantId);
                continue;
            }

            String gwId = gw.getGwId();
            Map<String,Object> attributes = rexolarApiClient.getDeviceAttributes(gwId, token, new String[]{Constants.LAST_ACTIVITY_TIME});
            if(CollectionUtils.isEmpty(attributes)){
//                log.error("syncGwStatus getDeviceAttributes error, gwId:{}", gwId);
                continue;
            }
            gw.setStatus(GwStatusEnum.ON.getCode());
            gw.setGmtModified(new Date());
            if(gatewayCredentialsService.updateById(gw)==1){
                log.error("syncGwStatus update gatewayCredentials error, gw:{}", gw);
            }
        }
//        log.info("syncGwStatus end, time:{}", System.currentTimeMillis()-startTime);
    }

    /**
     */
    @Scheduled(fixedRate = 60 * 1000)
    public void syncGwDeviceRelation() {
        long startTime = System.currentTimeMillis();
//        log.info("syncGwDeviceRelation start, time:{}", startTime);
        LambdaQueryWrapper<PaasGatewayCredentials> queryWrapper = new LambdaQueryWrapper<PaasGatewayCredentials>();
        queryWrapper.eq(PaasGatewayCredentials::getStatus, GwStatusEnum.ON.getCode());
        List<PaasGatewayCredentials> gwList = gatewayCredentialsService.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(gwList)){
            return;
        }
        for (PaasGatewayCredentials gw : gwList) {
            String gwId = gw.getGwId();
            String tenantId = gw.getTenantId();
            String token = rexolarApiClient.getTenantToken(tenantId);
            if(StringUtils.isEmpty(token)){
//                log.error("syncGwDeviceRelation getToken error, tenantId:{}", tenantId);
                continue;
            }
            LambdaQueryWrapper<PaasGatewayDeviceRelation> relationWrapper = new LambdaQueryWrapper<>();
            relationWrapper.eq(PaasGatewayDeviceRelation::getGwId, gwId);
            paasGatewayDeviceRelationService.delete(relationWrapper);

            List<DeviceBasicData> deviceList = rexolarApiClient.getFromRelationsInfo(token, gwId);
            if(!CollectionUtils.isEmpty(deviceList)){
                for (DeviceBasicData device : deviceList) {
                    PaasGatewayDeviceRelation relation = new PaasGatewayDeviceRelation();
                    relation.setDeviceId(device.getCoreId());
                    relation.setDeviceName(device.getName());
                    relation.setGwId(gwId);
                    relation.setStatus(1);
                    relation.setTenantId(gw.getTenantId());
                    relation.setGmtCreate(new Date());
                    relation.setGmtModified(new Date());
                    if(paasGatewayDeviceRelationService.insert(relation)==1){
                        log.error("syncGwDeviceRelation save relation failed, gwId:{}", gwId);
                    }
                }
            }
        }
//        log.info("syncGwDeviceRelation end, time:{}", System.currentTimeMillis()-startTime);
    }
}
